/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.jili.ubert.clientapi;

import com.jili.ubert.clientapi.until.AnswerHandler;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 *
 * @author dragon
 */
abstract class ListenBucketABS<T> {
    private final HashMap<String, List<AnswerHandler<T>>> listenHandlerMap;
    public ListenBucketABS(){listenHandlerMap = new HashMap<>(2^5);}
    public ListenBucketABS(int contains){
        listenHandlerMap = new HashMap<>(contains);
    }
    public void Register(String id, AnswerHandler<T> hander) {
        if (this.listenHandlerMap.containsKey(id)) {
            this.listenHandlerMap.get(id).add(hander);
        } else {
            List<AnswerHandler<T>> handlerList = new ArrayList<>();
            handlerList.add(hander);
            this.listenHandlerMap.put(id, handlerList);
        }

    }

    public void OnDealListen(T data) {
        String id = getKey(data);
        if (listenHandlerMap.containsKey(id)) {
            listenHandlerMap.get(id).stream().forEach((AnswerHandler<T> handler) -> {
                handler.OnAnswer(data);
            });
        }
        if (listenHandlerMap.containsKey("all")) {
            listenHandlerMap.get(id).stream().forEach((AnswerHandler<T> handler) -> {
                handler.OnAnswer(data);
            });
        }
    }

    public void CancelRegister(String id) {
        if (this.listenHandlerMap.containsKey(id)) {
            listenHandlerMap.remove(id);
        }
    }

    public void CancelRegister(AnswerHandler<T> hander) {
        listenHandlerMap.keySet().stream().forEach((key) -> {
            List<AnswerHandler<T>> handlerList = listenHandlerMap.get(key);
            if (handlerList.contains(hander)) {
                handlerList.remove(hander);
                if (handlerList.isEmpty()) {
                    listenHandlerMap.remove(key);
                }
            }
        });
    }

    public void CancelRegister(String id, AnswerHandler<T> hander) {
        if (this.listenHandlerMap.containsKey(id)) {
            if (listenHandlerMap.get(id).size() == 1 && listenHandlerMap.get(id).contains(hander)) {
                listenHandlerMap.remove(id);
            } else {
                listenHandlerMap.get(id).remove(hander);
            }
        }
    }
    public abstract String getKey(T data);
}
